package com.ultron.core.auth.filter;

import cn.hutool.json.JSONUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTPayload;
import cn.hutool.jwt.JWTUtil;
import com.ultron.common.entity.auth.AuthBaseVO;
import com.ultron.common.util.DateUtils;
import com.ultron.core.auth.UserContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;

/**
 * 标题：身份验证过滤器
 * 说明：身份验证过滤器，根据请求中的jwt信息解析用户个人信息并保存到线程
 * 时间：2023/3/17
 * 作者：admin
 */
@WebFilter(
        filterName = "AuthFilter",
        urlPatterns = {"/*"}
)
@Component
@Order(2)
@Slf4j
public class AuthFilter implements Filter {

    /**
     * Token名称
     */
    @Value("${access-token-name}")
    private String accessTokenName;
    /**
     * 参数携带Token名
     */
    private final static String paramTokenName = "token";


    @Override
    public void init(FilterConfig filterConfig) {


    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("=============进入认证过滤器=============");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        //请求token
        String token = request.getHeader(accessTokenName);
        //第一次为空，则看参数中是否带
        if (StringUtils.isBlank(token)) {
            token = request.getParameter(paramTokenName);
        }
        //token为空，直接放行，网关已做控制
        if (StringUtils.isBlank(token)) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            JWT jwt = JWTUtil.parseToken(token);
            JWTPayload payload = jwt.getPayload();
            AuthBaseVO authBaseVO = JSONUtil.toBean(payload.getClaimsJson(), AuthBaseVO.class);
            Date expireTime = authBaseVO.getExpireTime();
            //过期控制
            if (expireTime.compareTo(DateUtils.getCurrentDateYYYYMMDDHHMMSS()) > 0) {
                //保存到线程
                UserContextHolder.holder.set(authBaseVO);
                filterChain.doFilter(servletRequest, servletResponse);
            } else {
                PermissionExceptionResponse.rsp(response);
            }
        }
        //清理线程中的用户信息
        UserContextHolder.remove();
        log.info("=============完成认证过滤器=============");
    }


    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
